﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using l1cs.server.datatables;
using l1cs.server.templates;
using l1cs.server.model.Instance;

namespace l1cs.server.model
{
    public class L1MobGroupSpawn
    {
        private static Logger _log = Logger.getLogger( typeof( L1MobGroupSpawn ).FullName );

        private static L1MobGroupSpawn _instance;

        private static Random _random = new Random();

        private bool _isRespawnScreen;

        private bool _isInitSpawn;

        private L1MobGroupSpawn() { }

        public static L1MobGroupSpawn getInstance()
        {
            if ( _instance == null )
            {
                _instance = new L1MobGroupSpawn();
            }
            return _instance;
        }

        public void doSpawn( L1NpcInstance leader, int groupId, bool isRespawnScreen, bool isInitSpawn )
        {

            L1MobGroup mobGroup = MobGroupTable.getInstance().getTemplate( groupId );
            if ( mobGroup == null )
            {
                return;
            }

            L1NpcInstance mob;
            _isRespawnScreen = isRespawnScreen;
            _isInitSpawn = isInitSpawn;

            L1MobGroupInfo mobGroupInfo = new L1MobGroupInfo();

            mobGroupInfo.setRemoveGroup( mobGroup.isRemoveGroupIfLeaderDie() );
            mobGroupInfo.addMember( leader );

            foreach ( L1NpcCount minion in mobGroup.getMinions() )
            {
                if ( minion.isZero() )
                {
                    continue;
                }
                for ( int i = 0; i < minion.getCount(); i++ )
                {
                    mob = spawn( leader, minion.getId() );
                    if ( mob != null )
                    {
                        mobGroupInfo.addMember( mob );
                    }
                }
            }
        }

        private L1NpcInstance spawn( L1NpcInstance leader, int npcId )
        {
            L1NpcInstance mob = null;
            mob = NpcTable.getInstance().newNpcInstance( npcId );

            mob.setId( IdFactory.getInstance().nextId() );

            mob.setHeading( leader.getHeading() );
            mob.setMap( leader.getMapId() );
            mob.setMovementDistance( leader.getMovementDistance() );
            mob.setRest( leader.isRest() );

            mob.setX( leader.getX() + _random.Next( 5 ) - 2 );
            mob.setY( leader.getY() + _random.Next( 5 ) - 2 );
            // マップ外、障害物上、画面内沸き不可で画面内にPCがいる場合、リーダーと同じ座標
            if ( !canSpawn( mob ) )
            {
                mob.setX( leader.getX() );
                mob.setY( leader.getY() );
            }
            mob.setHomeX( mob.getX() );
            mob.setHomeY( mob.getY() );

            if ( mob is L1MonsterInstance )
            {
                ( (L1MonsterInstance)mob ).initHideForMinion( leader );
            }

            mob.setSpawn( leader.getSpawn() );
            mob.setreSpawn( leader.isReSpawn() );
            mob.setSpawnNumber( leader.getSpawnNumber() );

            if ( mob is L1MonsterInstance )
            {
                if ( mob.getMapId() == 666 )
                {
                    ( (L1MonsterInstance)mob ).set_storeDroped( true );
                }
            }

            L1World.getInstance().storeObject( mob );
            L1World.getInstance().addVisibleObject( mob );

            if ( mob is L1MonsterInstance )
            {
                if ( !_isInitSpawn && mob.getHiddenStatus() == 0 )
                {
                    mob.onNpcAI(); // モンスターのＡＩを開始
                }
            }
            mob.turnOnOffLight();
            mob.startChat( L1NpcInstance.CHAT_TIMING_APPEARANCE ); // チャット開始

            return mob;
        }

        private bool canSpawn( L1NpcInstance mob )
        {
            if ( mob.getMap().isInMap( mob.getLocation() )
                    && mob.getMap().isPassable( mob.getLocation() ) )
            {
                if ( _isRespawnScreen )
                {
                    return true;
                }
                if ( L1World.getInstance().getVisiblePlayer( mob ).Count == 0 )
                {
                    return true;
                }
            }
            return false;
        }
    }
}
